﻿//Copyright (C) <2013>  <jonathan cleeve norton> All Rights Reserved 
//Contact jon.norton@fin-plus.co.uk website <http://www.fin-plus.co.uk/>
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using FinPlusAssembler;
using FinPlusInterfaces;

namespace FinPlusStubRateServer
{
    public class Generate
    {
        private readonly ITransport _tran;
        private readonly Config _config;
        private readonly int _waitMilliseconds;
        private string[] types = { "Open", "Buy", "Sell", "Mid", "Last" };

        //construct
        public Generate(ITransport tran, Dictionary<string, Dictionary<string, string>> products, int waitMilliseconds)
        {
            _tran = tran;
            _waitMilliseconds = waitMilliseconds;
            _config = new Config();

            foreach (KeyValuePair<string, Dictionary<string, string>> item in products)
                if (item.Value.ContainsKey("Topic") && item.Value.ContainsKey("Handle") && item.Value.ContainsKey("Open"))
                {
                    item.Value["Live"] = item.Value["Open"];
                    _config[item.Key] = item.Value;
                }
        }

        //public
        public void PublishClose()
        {
            try
            {
                Parallel.ForEach(_config.Values, item =>
                {
                    double value = double.Parse(item["Live"]);
                    var message = IOC.New<IMessage>(value, item["Topic"] + "." + item["Handle"] + ".Close");
                    _tran.Publish(message);
                });
            }
            catch
            {
                throw;
            }
        }

        public void PublishLive()
        {
            try
            {
                do
                {
                    Parallel.ForEach(_config.Values, item =>
                    //foreach (Dictionary<string, string> item in _products.Values)
                    {
                        System.Threading.Thread.Sleep(_waitMilliseconds);

                        Random rnd = new Random();
                        double value = double.Parse(item["Live"]);
                        double open = double.Parse(item["Open"]);
                        double limit = double.Parse(item["Limit"]);

                        double step = double.Parse(item["RandomStep"]);
                        int r = rnd.Next(0, 2);
                        double newValue = r == 0 ? value - step : value + step;
                        item["Live"] = value.ToString();

                        if (newValue > open - limit && newValue < open + limit)
                        {
                            value = newValue;
                            item["Level"] = value.ToString();

                            foreach (var type in types)
                            {
                                double adj = double.Parse(item[type]);
                                var message = IOC.New<IMessage>(value, item["Topic"] + "." + item["Handle"] + "." + type);
                                _tran.Publish(message);
                            }
                        }
                    //}
                    });
                }
                while (true);
            }
            catch
            {
                throw;
            }
        }
    }
}
